package cn.thr.pethome.permission.service.impl;

import cn.thr.pethome.annotation.PreAuthorize;
import cn.thr.pethome.permission.domain.Permission;
import cn.thr.pethome.permission.mapper.PermissionMapper;
import cn.thr.pethome.permission.service.IPermissionService;
import cn.thr.pethome.base.service.Impl.BaseServiceImpl;
import cn.thr.pethome.util.Classutil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PreDestroy;
import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author thr
 * @since 2023-02-02
 */
@Service
public class PermissionServiceImpl extends BaseServiceImpl<Permission> implements IPermissionService {
    private static final String  PKG_PREFIX   = "cn.thr.pethome.";
    private static final String  PKG_SUFFIX   = ".controller";
    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public void automaticScanning() {
        //1.扫描注解 加载注解要去找编译文件
        //获取org.yaosang下面所有的模块目录
        String path = this.getClass().getResource("/").getPath() + "cn/thr/pethome/";
        File file = new File(path);
        File[] files = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isDirectory();
            }
        });

        //1.1 找到文件路径  扫描里面所有类的方法
        //获取org.yaosang.*.web.controller里面所有的类
        Set<Class> clazzes = new HashSet<>();
        for (File fileTmp : files) {
            System.out.println(fileTmp.getName());
            clazzes.addAll(Classutil.getClasses(PKG_PREFIX+fileTmp.getName()+PKG_SUFFIX));
        }
        for (Class clazz : clazzes) {
            Method[] methods = clazz.getMethods(); //得到当前类的所有的方法
            if(methods == null){  //如果这里类里面的方法为null的话，就停止本次的循环
                continue;  //停止
            }
            for (Method method : methods) {  //遍历所有的方法
                String uri = getUri(clazz, method); //每一次都要获取uri
                PreAuthorize annotation = method.getAnnotation(PreAuthorize.class);//获取指定注解
                if(annotation == null){  //因为不能保证所有类上都会有注解  所有如果等于null 就暂停循环
                    continue;
                }

                //获取注解数据
                String name = annotation.name();  //这两个是注解里面的值
                String value = annotation.value();

                //保存到数据库里面去
                Permission permission = new Permission();
                permission.setName(name);
                permission.setSn(value);
                permission.setUrl(uri);
                Permission bySn = permissionMapper.findBySn(value); //用来查询 permission sn 有没有数据
                if(bySn == null){  //如果sn 为空的话就执行添加  没有的话就不执行添加
                    permissionMapper.add(permission);
                }
            }
        }
    }

    private String getUri(Class clazz, Method method) {
        String classPath = "";
        Annotation annotation = clazz.getAnnotation(RequestMapping.class);
        if (annotation!=null){
            RequestMapping requestMapping = (RequestMapping) annotation;
            String[] values = requestMapping.value();
            if(values!=null&&values.length>0){
                classPath = values[0];
                if (!"".equals(classPath)&&!classPath.startsWith("/"))
                    classPath="/"+classPath;
            }
        }
        GetMapping getMapping =  method.getAnnotation(GetMapping.class);
        String methodPath = "";
        if (getMapping!=null){
            String[] values = getMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        PostMapping postMapping =  method.getAnnotation(PostMapping.class);
        if (postMapping!=null){
            String[] values = postMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        DeleteMapping deleteMapping =  method.getAnnotation(DeleteMapping.class);
        if (deleteMapping!=null){
            String[] values = deleteMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        PutMapping putMapping =  method.getAnnotation(PutMapping.class);
        if (putMapping!=null){
            String[] values = putMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }

        }
        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if (patchMapping!=null){
            String[] values = patchMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if (requestMapping!=null){
            String[] values = requestMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        return classPath+methodPath;
    }

    private String getPermissionSn(String value) {
        String regex = "\\[(.*?)]";
        Pattern p = Pattern.compile("(?<=\\()[^\\)]+");
        Matcher m = p.matcher(value);
        String permissionSn =null;
        if (m.find()){
            permissionSn= m.group(0).substring(1, m.group().length()-1);
        }
        return permissionSn;
    }
}
